home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / cmdity / yk212src.lha / Yak_2.12_Src / settings.c < prev    next >
C/C++ Source or Header  |  1995-11-22  |  28KB  |  929 lines

  1. #define __USE_SYSBASE
  2. #include <exec/types.h>
  3. #include <exec/memory.h>
  4. #include <dos/dos.h>
  5. #include <libraries/iffparse.h>
  6. #include <prefs/prefhdr.h>
  7. #include <proto/exec.h>
  8. #include <proto/dos.h>
  9. #include <proto/iffparse.h>
  10. #include <string.h>
  11.  
  12. #include "code.h"
  13. #include "yak.h"
  14. #include "Requesters.h"
  15. #include "handlers.h"
  16. #include "hotkey_types.h"
  17. #include "Settings.h"
  18. #include "DigitalClock.h"
  19.  
  20.  
  21. #define CATCOMP_NUMBERS
  22. #include "yak_locale_strings.h"
  23.  
  24. extern struct Library *IFFParseBase;
  25.  
  26. #if defined (PREFS) || defined (CONV)
  27. #  ifdef _DCC
  28. #    include <lists.h>
  29. #  else
  30. #    include "sas_lists.h"
  31. #  endif
  32. #  include "gui.h"
  33. #  include "Root_window.h"
  34. #  include "MouseCycling_window.h"
  35. #  include "Options_window.h"
  36. #  include "KeyDef_window.h"
  37. #  include "Blank_window.h"
  38. #  include "Misc_window.h"
  39. #  include "Hotkey_window.h"
  40.    static APTR WriteConfig(struct IFFHandle *iff, UBYTE *chunkbuf);
  41.    static APTR WriteHandlers(struct IFFHandle *iff, UBYTE *chunkbuf);
  42.    static APTR WriteHotkey(struct IFFHandle *iff, UBYTE *chunkbuf, YakHotKey *yhk);
  43. #else
  44. #  include "ClickDrive.h"
  45. #  include "BlackBorder.h"
  46. #  include "MMB_Shift.h"
  47. #  include "UnixDirs.h"
  48. #  include "FullWorkbench.h"
  49. #endif
  50.  
  51. #ifndef CONV
  52. static APTR ReadConfig(UBYTE *chunkbuf, ULONG size);
  53. static APTR ReadHandlers(UBYTE *chunkbuf, ULONG size);
  54. static APTR ReadHotkey(UBYTE *chunkbuf, ULONG size);
  55. #endif
  56.  
  57. static UWORD PrefsVersionRead;
  58.  
  59. /*
  60.  * Used for compatibility
  61.  *
  62.  * +----------------+-------------+
  63.  * |YAKPREFSVERSION | Yak version |
  64.  * +----------------+-------------+
  65.  * | 0              | Yak 2.00    |
  66.  * | 1              | Yak 2.04    |
  67.  * +----------------+-------------+
  68.  */
  69.  
  70. #define YAKPREFSVERSION 1
  71.  
  72.  
  73.  
  74.  
  75. #define MAXBUFSIZE 1024
  76.  
  77.  
  78. #define DEF_AUTOPOINT_DELAY    2
  79. ULONG    autopoint_delay;           /* used for autopoint */
  80.  
  81. #define DEF_VOLUME            48
  82. ULONG    click_volume;              /* used for keyclick */
  83.  
  84. #define DEF_SCREENBLANKSECS        300
  85. ULONG    blanksecs; 
  86. ULONG    blanktimeout;
  87. ULONG    blankcount;                /* countdown to blank-time */
  88. ULONG    screenblank;               /* method used to blank screen */
  89.  
  90. #define DEF_MOUSEBLANKSECS         5
  91. ULONG    mouseblank;                /* method used to blank mouse */
  92. ULONG    mblanksecs;
  93. ULONG    mblanktimeout;
  94. ULONG    mblankcount;               /* countdown to mouse-blank-time */
  95.  
  96. static const BOOL DEF_TOGGLE[NUM_TOGGLES] = {
  97.         TRUE,         /* autopoint       */
  98.         FALSE,        /* keyactivate     */
  99.         FALSE,        /* autopop         */
  100.         FALSE,        /* rmbactivate     */
  101.         FALSE,        /* wildstar        */
  102.         TRUE,         /* scractivate     */
  103.         FALSE,        /* noclick         */
  104.         FALSE,        /* mmbactivate     */
  105.         FALSE,        /* blackborder     */
  106.         TRUE,         /* blankmouseonkey */
  107.         FALSE,        /* mmbshift        */
  108.         FALSE,        /* UnixDirs        */
  109.         FALSE,        /* SlashDir        */
  110.         FALSE,        /* fullworkbench   */
  111.         FALSE         /* CapShift        */
  112. };
  113.  
  114.  
  115.  
  116. #ifdef PREFS
  117.  
  118. #  define TOGGLE_DESCRIPTION(DefState, Gadget, WindowID) {(BOOL)DefState, (UWORD)Gadget, (UBYTE)WindowID}
  119.  
  120. #else   /* Yak commodity only */
  121.  
  122. #  define TOGGLE_DESCRIPTION(DefState, Gadget, WindowID) {(BOOL)DefState}
  123.  
  124. #endif
  125.  
  126. ToggleData toggles[] = {
  127.         TOGGLE_DESCRIPTION( TRUE, GDX_AutoCheck,          ROOT_WINDOW),
  128.         TOGGLE_DESCRIPTION(FALSE, GDX_KeyActCheck,        ROOT_WINDOW),
  129.         TOGGLE_DESCRIPTION(FALSE, GDX_AutoPopCheck,       ROOT_WINDOW),
  130.         TOGGLE_DESCRIPTION(FALSE, GDX_RMBActCheck,        ROOT_WINDOW),
  131.         TOGGLE_DESCRIPTION(FALSE, GDX_WildStarCheck,      MISC_WINDOW),
  132.         TOGGLE_DESCRIPTION( TRUE, GDX_ScrActCheck,        ROOT_WINDOW),
  133.         TOGGLE_DESCRIPTION(FALSE, GDX_NoClickCheck,       MISC_WINDOW),
  134.         TOGGLE_DESCRIPTION(FALSE, GDX_MMBActCheck,        ROOT_WINDOW),
  135.         TOGGLE_DESCRIPTION(FALSE, GDX_BlackBorderCheck,   MISC_WINDOW),
  136.         TOGGLE_DESCRIPTION( TRUE, GDX_BlankMouseOnKey,    BLANK_WINDOW),
  137.         TOGGLE_DESCRIPTION(FALSE, GDX_MMBShiftCheck,      MISC_WINDOW),
  138.         TOGGLE_DESCRIPTION(FALSE, GDX_UnixDirsCheck,      MISC_WINDOW),
  139.         TOGGLE_DESCRIPTION(FALSE, GDX_SlashDirCheck,      MISC_WINDOW),
  140.         TOGGLE_DESCRIPTION(FALSE, GDX_FullWorkbenchCheck, MISC_WINDOW),
  141.         TOGGLE_DESCRIPTION(FALSE, GDX_CapShiftCheck,      MISC_WINDOW)
  142. };
  143.  
  144.  
  145. static const char *DEF_PATTERN[NUM_PATTERNS] = {
  146.          "#?",               /* autoactivation screens */
  147.          "~(Workbench)"      /* autopop windows */
  148. };
  149.  
  150. PatternData patterns[NUM_PATTERNS] = {
  151.         { "#?", NULL },                 /* autoactivation screens */
  152.         { "~(Workbench)", NULL }        /* autopop windows */
  153. };
  154.  
  155.  
  156.  
  157.  
  158. /* Chunks to stop on */
  159. #define NUMSTOPS 4
  160.  
  161. LONG stopchunks[] = {
  162.         ID_PREF, ID_YKCF,
  163.         ID_PREF, ID_YKHD,
  164.         ID_PREF, ID_YKHK,
  165.         ID_PREF, ID_YKDC
  166. };
  167.  
  168. struct PrefHeader PrefHdrChunk = {
  169.       YAKPREFSVERSION, 0, 0
  170. };
  171.  
  172.  
  173.  
  174. /* parse pattern, report errors */
  175. __regargs BOOL
  176. InitPattern(char *newpatstr, PatternData *pdata)
  177. {
  178.         char *patstr = newpatstr ? newpatstr : pdata->patstr;
  179.         char *pat;
  180.         LONG len;
  181.  
  182.         if (pat = AllocVec(len = strlen(patstr)*3+10, MEMF_CLEAR))
  183.         {
  184.                 if (ParsePattern(patstr, pat, len) != -1)
  185.                 {
  186.                         if (newpatstr) strncpy(pdata->patstr, newpatstr, PATLEN);
  187.                         if (pdata->pat) FreeVec(pdata->pat); 
  188.                         pdata->pat = pat;
  189.                         return TRUE;
  190.                 }
  191.                 
  192.                 PostError("%s:\n\"%s\"", getString(Parsing_Pattern_ERR), patstr);
  193.                 FreeVec(pat);
  194.         }
  195.         else PostError(getString(Allocation_ERR));
  196.         return FALSE;
  197. }
  198.  
  199.  
  200. /* Set default settings */
  201. void
  202. SetDefaultSettings(void)
  203. {
  204.     register UWORD   i;
  205.  
  206.     /* Config */
  207.     for (i=0; i < NUM_TOGGLES; i++)
  208.         toggles[i].pos = DEF_TOGGLE[i];
  209.  
  210.     for (i=0; i< NUM_PATTERNS; i++)
  211.         strcpy(patterns[i].patstr, DEF_PATTERN[i]);
  212.  
  213.     autopoint_delay = DEF_AUTOPOINT_DELAY;
  214.     click_volume    = DEF_VOLUME;
  215.     blanksecs       = DEF_SCREENBLANKSECS;
  216.     mblanksecs      = DEF_MOUSEBLANKSECS;
  217.     mouseblank      = MB_SPRITES;
  218.     screenblank     = SB_BLACKSCREEN;
  219.  
  220.     /* Hotkeys */
  221.     DeleteYakHotKeyList();
  222.  
  223.     /* Mouse Cycling */
  224.     CleanMouseCycling();
  225.     for (i=0; i<NUM_HANDLERS; i++)
  226.     {
  227.         CopyMem((char *)&DEF_MOUSECYCLING[i], (char *)&MouseCyclingHandlers[i], (long)sizeof(YakHandler));
  228.         MouseCyclingHandlers[i].KeyDef = DupStr(MouseCyclingHandlers[i].KeyDef);
  229.     }
  230.  
  231.     /* Digital Clock */
  232.     DC_F_Set_Default();
  233.  
  234. }
  235.  
  236. #ifndef CONV
  237.  
  238. /* Read Preferences */
  239. void
  240. LoadSettings(char *filename)
  241. {
  242.     struct IFFHandle *iff;
  243.     APTR              error = Opening_prefs_file_ERR; /* Temporarily */
  244.     BOOL              cont = TRUE;
  245.  
  246.     /* First: set default values */
  247.     SetDefaultSettings();
  248.  
  249.     /* Allocate IFF handle */
  250.     if (iff=AllocIFF())
  251.     {
  252.         /* Open IFF File */
  253.         if (iff->iff_Stream=Open(filename, MODE_OLDFILE))
  254.         {
  255.             /* Init IFF handle */
  256.             InitIFFasDOS(iff);
  257.  
  258.             /* Open IFF handle */
  259.             if (!OpenIFF(iff, IFFF_READ))
  260.             {
  261.                 /* Set IFF chunk types */
  262.                 if (!PropChunk(iff, ID_PREF, ID_PRHD) &&
  263.                     !StopChunks(iff, stopchunks, NUMSTOPS) &&
  264.                     !StopOnExit(iff, ID_PREF, ID_FORM) )
  265.                 {
  266.                     error = Invalid_prefs_file_ERR; /* Temporarily */
  267.  
  268.                     /* Start IFF parsing */
  269.                     if (!ParseIFF(iff, IFFPARSE_STEP))
  270.                     {
  271.                         struct ContextNode *cn;
  272.  
  273.                         /* Check IFF type */
  274.                         if ( (cn=CurrentChunk(iff)) &&
  275.                             (cn->cn_ID   == ID_FORM) &&
  276.                             (cn->cn_Type == ID_PREF) )
  277.                         {
  278.                             if (!ParseIFF(iff, IFFPARSE_SCAN))
  279.                             {
  280.                                 struct StoredProperty *sp;
  281.  
  282.                                 /* Get pointer to PRHD chunk */
  283.                                 if (sp=FindProp(iff, ID_PREF, ID_PRHD))
  284.                                 {
  285.                                     struct PrefHeader *ph=(struct PrefHeader *) sp->sp_Data;
  286.                             
  287.                                     PrefsVersionRead = ph->ph_Version;
  288.  
  289.                                     error = NULL; /* No error: temporarily */
  290.  
  291.                                     /* Parse IFF chunks */
  292.                                     do
  293.                                     {
  294.                                         APTR   localerr;
  295.                                         char   localstr[5];
  296.  
  297.                                         /* Get current chunk */
  298.                                         if (cn=CurrentChunk(iff))
  299.                                         {
  300.                                             UBYTE *chunkbuf;
  301.                                             ULONG  size=cn->cn_Size;
  302.  
  303.                                             /* Allocate memory for config buffer */
  304.                                             if (chunkbuf=AllocVec(size, 0L))
  305.                                             {
  306.                                                 /* Read chunk */
  307.                                                 if (ReadChunkBytes(iff, chunkbuf, size) == size)
  308.                                                 {
  309.                                                     switch(cn->cn_ID) 
  310.                                                     {
  311.                                                       case ID_YKCF:
  312.                                                         localerr = ReadConfig(chunkbuf, size);
  313.                                                         break;
  314.                                                       case ID_YKHK:
  315.                                                         localerr = ReadHotkey(chunkbuf, size);
  316.                                                         break;      
  317.                                                       case ID_YKHD:
  318.                                                         localerr = ReadHandlers(chunkbuf, size);
  319.                                                         break;      
  320.                                                       case ID_YKDC:
  321.                                                         localerr = ReadDigitalClock(chunkbuf, size);
  322.                                                         break;
  323.                                                     }
  324.                                                     if (localerr)
  325.                                                     {
  326.                                                         cont = (BOOL)GetOrders(getString(Continue_Abort_ORDERS),
  327.                                                                                getString(localerr),
  328.                                                                                IDtoStr(cn->cn_ID, localstr));
  329.                                                     }
  330.                                                 }
  331.                                                 else
  332.                                                 {
  333.                                                     PostError(getString(Reading_prefs_file_ERR));
  334.                                                     cont = FALSE;
  335.                                                 }
  336.  
  337.                                                 FreeVec(chunkbuf);
  338.                                             }
  339.                                             else
  340.                                             {
  341.                                                 PostError(getString(Allocation_ERR));
  342.                                                 cont = FALSE;
  343.                                             }
  344.                                         }
  345.                                         /* Next parse step */
  346.                                     } while ((!ParseIFF(iff, IFFPARSE_SCAN)) && cont);
  347.                                 }
  348.                             }
  349.                         }
  350.                     }
  351.                 }
  352.                 CloseIFF(iff);
  353.             }
  354.             Close(iff->iff_Stream);
  355.         }
  356.         FreeIFF(iff);
  357.     }
  358.     else
  359.         PostError(getString(Allocation_ERR));
  360.  
  361.     if (error)
  362.         PostError("%s\n\"%s\"", getString(error), filename);                                                    
  363. }
  364.  
  365.  
  366.  
  367.  
  368. /* YKCF chunk format
  369.  *
  370.  *      UWORD NUM_TOGGLES
  371.  *        BOOL toggles[]
  372.  *      UWORD click_volume
  373.  *      UWORD autopoint_delay
  374.  *      UWORD blanksecs
  375.  *      UWORD mblanksecs
  376.  *      UWORD mouseblank
  377.  *      UWORD screenblank 
  378.  *      UWORD NUM_PATTERNS
  379.  *        STRING patterns[]
  380.  */
  381. static APTR
  382. ReadConfig(UBYTE *chunkbuf, ULONG size)
  383. {
  384.     UWORD *puword=(UWORD *)chunkbuf;
  385.     BOOL  *pbool;
  386.     UBYTE *pstr;
  387.     UWORD   i, n;
  388.  
  389.     if ((n=*puword) > (UWORD)NUM_TOGGLES)
  390.     {
  391.         n = (UWORD) NUM_TOGGLES;
  392.     }
  393.     pbool = puword+1;
  394.     for (i = 0; i < n; i++)
  395.         toggles[i].pos = *pbool++;
  396.     puword = pbool;
  397.         
  398.     /* Miscellaneous */
  399.         
  400.     click_volume    = *puword++;
  401.     autopoint_delay = *puword++;
  402.     blanksecs       = *puword++;
  403.     mblanksecs      = *puword++;
  404.     mouseblank      = *puword++;
  405.     
  406.     if ((mblanksecs == 0) && (blankmouseonkey == FALSE))
  407.     {
  408.         mouseblank = MB_NONE;
  409.     }
  410.  
  411.     if (PrefsVersionRead > 0)
  412.     {
  413.         screenblank = *puword++;
  414.         if (blanksecs == 0)
  415.         {
  416.             screenblank = SB_NONE;
  417.         }
  418.     }
  419.  
  420.     if ((n=*puword++) <= NUM_PATTERNS)
  421.     {
  422.         pstr = (UBYTE *)puword;
  423.         for (i = 0; i < n; i++)
  424.         {
  425.             strncpy(patterns[i].patstr, pstr, PATLEN);
  426.             patterns[i].patstr[PATLEN] = '\0';
  427.             pstr += strlen(pstr)+1;
  428.         }
  429.  
  430.  
  431. #ifndef PREFS                   /* Yak */
  432.         /* set-up patterns */
  433.         for (i = 0; i < NUM_PATTERNS; i++)
  434.             InitPattern(NULL, &patterns[i]);
  435.  
  436.         if (wildstar)
  437.             WILDSTARON;
  438.         else
  439.             WILDSTAROFF;
  440.  
  441.         SetClickDrive(noclick);
  442.  
  443.         ToggleBlackBorder(blackborder);
  444.  
  445.         ToggleFullWorkbench(fullworkbench);
  446.  
  447.         ToggleUnixDirs(unixdirs);
  448.  
  449.         ToggleMMBShift(mmbshift);
  450.  
  451.         blankcount  = blanktimeout  = 10*blanksecs;
  452.         mblankcount = mblanktimeout = 10*mblanksecs;
  453. #endif
  454.  
  455.         if ((pstr-chunkbuf) == size)
  456.         { 
  457.             /* Reading Ok */
  458.             return 0L;
  459.         }
  460.  
  461.     }
  462.     return Reading_chunk_ERR;
  463. }
  464.  
  465.  
  466.  
  467. /* YKHK chunk format
  468.  *
  469.  *      UWORD  type
  470.  *      UWORD  state
  471.  *      STRING name
  472.  *      STRING keydef
  473.  *      UWORD  optsnum
  474.  *         UWORD flags
  475.  *         [ STRING argstr[] ]
  476.  *         [ LONG   argnum[] ]
  477.  *                .
  478.  *                .
  479.  *                .
  480.  *
  481.  */
  482. static APTR
  483. ReadHotkey(UBYTE *chunkbuf, ULONG size)
  484. {
  485.     register UWORD *puword=(UWORD *)chunkbuf;
  486.     register UBYTE *pstr;
  487.     void           *pvoid;
  488.     LONG           *plong;
  489.  
  490.     YakHotKey      *yhk;
  491.     UWORD           type;
  492.  
  493.     UWORD           ol, optsnum;
  494.     OptDescription *curdesc;
  495.  
  496.     if ((type=*puword++) < NUM_HOTKEY_TYPES)
  497.     {
  498.         if (yhk = NewYakHotKey(type))
  499.         {
  500.             yhk->yhk_State   = *puword++;         /* State */
  501.             pstr = (UBYTE *)puword;
  502.  
  503.             if (ModifyYHKName(yhk, pstr))         /* Name */
  504.             {
  505.                 pstr += strlen(pstr)+1;
  506.  
  507.                 /* Take care of non word aligned addresses for 68000 */
  508.                 puword = (UWORD *)WORD_ALIGN(pstr);
  509.  
  510.                 if (ModifyYHKKeyDef(yhk, pstr))   /* KeyDef */
  511.                 {
  512.                     pstr += strlen(pstr)+1;
  513.  
  514.                     /* Options */
  515.                     /* Take care of non word aligned addresses for 68000 */
  516.                     puword = (UWORD *)WORD_ALIGN(pstr);
  517.  
  518.                     optsnum = *puword++;
  519.                     pvoid   = (void *)puword;
  520.  
  521.                     for (ol=0; ol<optsnum; ol++)
  522.                     {
  523.                         UWORD as=0;   /* ArgStr number */
  524.                         UWORD an=0;   /* ArgNum number */
  525.  
  526.                         curdesc = yhktypes[yhk->yhk_Type].yhkt_OptsList[ol].Desc;
  527.  
  528.                         puword = (UWORD *)pvoid;
  529.                         yhk->yhk_Option[ol].Flags = *puword++;
  530.                         pvoid = (void *)puword;
  531.  
  532.                         while (curdesc->Type != NO_OPT)
  533.                         {
  534.                             switch(curdesc->Type)
  535.                             {
  536.                                 case STRING_OPT:
  537.                                     if (yhk->yhk_Option[ol].Flags & curdesc->LocalID)
  538.                                     {
  539.                                         pstr = (UBYTE *)pvoid;
  540.                                         yhk->yhk_Option[ol].ArgStr[as] = DupStr(pstr);
  541.                                         pstr += strlen(pstr)+1;
  542.  
  543.                                         /* Take care of non word aligned addresses for 68000 */
  544.                                         pvoid = (void *)WORD_ALIGN(pstr);
  545.                                     }
  546.                                     as++;
  547.                                     break;
  548.  
  549.                                 case INTEGER_OPT:
  550.                                     if (yhk->yhk_Option[ol].Flags & curdesc->LocalID)
  551.                                     {
  552.                                         plong = (LONG *)pvoid;
  553.                                         yhk->yhk_Option[ol].ArgNum[an] = *plong++;
  554.                                         pvoid = (void *)plong;
  555.                                     }
  556.                                     an++;
  557.                                     break;
  558.                             }
  559.  
  560.                             curdesc++;
  561.                         }
  562.                     }
  563.  
  564.                     if (((UBYTE *)pvoid-chunkbuf) == size)
  565.                         return 0L;  /* Reading Ok */
  566.  
  567.                 }
  568.  
  569.             }
  570.  
  571.             DeleteYakHotKey(yhk);
  572.         }
  573.  
  574.     }
  575.  
  576.     return Reading_chunk_ERR;
  577. }
  578.  
  579.  
  580. /* YKHD chunk format
  581.  *
  582.  *      UWORD NUM_HANDLERS
  583.  *        UWORD  handler[0].State
  584.  *        UWORD  handler[0].RequiredClicks
  585.  *        STRING handler[0].KeyDef
  586.  *        STRING handler[0].ScreenPatternStr
  587.  *               .
  588.  *               .
  589.  *               .
  590.  */
  591. static APTR
  592. ReadHandlers(UBYTE *chunkbuf, ULONG size)
  593. {
  594.     register UWORD *puword=(UWORD *)chunkbuf;
  595.     register UBYTE *pstr;
  596.  
  597.     register UWORD   i,n;
  598.  
  599.     if ((n=*puword++) <= NUM_HANDLERS)
  600.     {
  601.         for (i = 0; i < n; i++)
  602.         {
  603.             char *keydef;
  604.  
  605.             MouseCyclingHandlers[i].State = *puword++;
  606.             
  607.             MouseCyclingHandlers[i].RequiredClicks = *puword++;
  608.             
  609.             MouseCyclingHandlers[i].Options = *puword++;
  610.             
  611.             pstr = (UBYTE *)puword;
  612.  
  613.             keydef = DupStr(pstr);
  614.             if (MouseCyclingHandlers[i].KeyDef)
  615.                 FreeVec(MouseCyclingHandlers[i].KeyDef);
  616.             MouseCyclingHandlers[i].KeyDef = keydef;
  617.  
  618.             pstr += strlen(pstr)+1;
  619.             
  620.             strncpy(MouseCyclingHandlers[i].ScreenPatternData.patstr, pstr, PATLEN);
  621.  
  622.             pstr += strlen(pstr)+1;
  623.  
  624.             /* Take care of non word aligned addresses for 68000 */
  625.             puword = (UWORD *)WORD_ALIGN(pstr);
  626.  
  627.         }
  628.  
  629.         ToggleMouseCycling();
  630.  
  631.         if (((UBYTE *)puword-chunkbuf) == size)
  632.             return 0L;          /* Reading Ok */
  633.     }
  634.     return Reading_chunk_ERR;
  635. }
  636.  
  637.  
  638.  
  639. #endif
  640.  
  641. #if defined(PREFS) || defined(CONV)
  642.  
  643. /* Copy a file */
  644. #define COPYBUFSIZE 2048
  645. BOOL
  646. CopyFile(char *source, char *dest)
  647. {
  648.     BOOL  ret=FALSE;
  649.     char *copybuf;
  650.  
  651.     /* Allocate copy buffer */
  652.     if (copybuf= AllocMem(COPYBUFSIZE, 0))
  653.     {
  654.         BPTR infh;
  655.  
  656.         /* Open source file */
  657.         if (infh=Open(source, MODE_OLDFILE))
  658.         {
  659.             BPTR outfh;
  660.  
  661.             /* Open destination file */
  662.             if (outfh=Open(dest, MODE_NEWFILE))
  663.             {
  664.                 LONG n;
  665.  
  666.                 /* Copy file */
  667.                 while ((n=Read(infh, copybuf, COPYBUFSIZE)) > 0)
  668.                     if (Write(outfh, copybuf, n) != n) break;
  669.  
  670.                 /* No error? */
  671.                 if (!n) ret=TRUE;
  672.  
  673.                 Close(outfh);
  674.             }
  675.             Close(infh);
  676.         }
  677.         FreeMem(copybuf, COPYBUFSIZE);
  678.     }
  679.     else
  680.         PostError(getString(Allocation_ERR));
  681.  
  682.  
  683.     return ret;
  684. }
  685.  
  686.  
  687. /* Write Preferences */
  688. void
  689. SaveSettings(char *filename)
  690. {
  691.     UBYTE *chunkbuf;
  692.     APTR   error = Opening_prefs_file_ERR; /* Temporarily */
  693.  
  694.     /* Allocate memory for config buffer */
  695.     if (chunkbuf=AllocVec(MAXBUFSIZE, 0L))
  696.     {
  697.         struct IFFHandle *iff;
  698.  
  699.         /* Allocate IFF handle */
  700.         if (iff=AllocIFF())
  701.         {
  702.             /* Open IFF File */
  703.             if (iff->iff_Stream=Open(filename, MODE_NEWFILE))
  704.             {
  705.                 /* Init IFF handle */
  706.                 InitIFFasDOS(iff);
  707.  
  708.                 /* Open IFF handle */
  709.                 if (!OpenIFF(iff, IFFF_WRITE))
  710.                 {
  711.                     error = Writing_prefs_file_ERR; /* Temporarily */
  712.  
  713.                     /* Push FORM IFF chunk */
  714.                     if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN))
  715.                     {
  716.                         /* Write PRHD IFF chunk */
  717.                         if (!PushChunk(iff, 0, ID_PRHD, sizeof(struct PrefHeader)) &&
  718.                             (WriteChunkBytes(iff, 
  719.                                              (UBYTE *) &PrefHdrChunk,
  720.                                              sizeof(struct PrefHeader)) == sizeof(struct PrefHeader)) &&
  721.                             !PopChunk(iff))
  722.                         {
  723.                             YakHotKey      *yhk;
  724.                             register UWORD  type;
  725.  
  726.                             error = WriteConfig(iff, chunkbuf);
  727.  
  728.                             if (!error) error = WriteHandlers(iff, chunkbuf);
  729.  
  730.                             for (type = 0; type < NUM_HOTKEY_TYPES && !error; type++)
  731.                                 for (yhk = (YakHotKey *)GetHead(keylist(type));
  732.                                      yhk && !error;
  733.                                      yhk = (YakHotKey *)GetSucc(yhk))
  734.                                 {
  735.                                     error = WriteHotkey(iff, chunkbuf, yhk);
  736.                                 }
  737.  
  738.                             if (!error) error = WriteDigitalClock(iff, chunkbuf);
  739.  
  740.                         }
  741.                         if (PopChunk(iff)) /* close out the FORM */
  742.                             error = Writing_prefs_file_ERR;
  743.                     }
  744.                     CloseIFF(iff);
  745.                 }
  746.                 Close(iff->iff_Stream);
  747.             }
  748.             FreeIFF(iff);
  749.         }
  750.         FreeVec(chunkbuf);
  751.     }
  752.     else
  753.         PostError(getString(Allocation_ERR));
  754.  
  755.     if (error)
  756.         PostError("%s\n\"%s\"", getString(error), filename);
  757. }
  758.  
  759.  
  760. static APTR
  761. WriteConfig(struct IFFHandle *iff, UBYTE *chunkbuf)
  762. {
  763.     register UWORD *puword=(UWORD *)chunkbuf;
  764.     register BOOL  *pbool;
  765.     register UBYTE *pstr;
  766.  
  767.     register UWORD i;
  768.     ULONG          size=0;
  769.  
  770.     /* toggles */
  771.     *puword++ =  (UWORD) NUM_TOGGLES;
  772.     pbool     = puword;
  773.     for (i = 0; i < NUM_TOGGLES; i++)
  774.             *pbool++ = toggles[i].pos;
  775.     puword    = pbool;
  776.  
  777.     /* miscellaneous */
  778.     *puword++ = click_volume;
  779.     *puword++ = autopoint_delay;
  780.     *puword++ = blanksecs;
  781.     *puword++ = mblanksecs;
  782.     *puword++ = mouseblank;
  783.     *puword++ = screenblank;
  784.  
  785.     /* patterns */
  786.     *puword++ = NUM_PATTERNS;
  787.     pstr      = (UBYTE *)puword;
  788.     for (i = 0; i < NUM_PATTERNS; i++)
  789.     {
  790.         strcpy(pstr, patterns[i].patstr);
  791.         pstr += strlen(pstr)+1;
  792.     }
  793.  
  794.     /* Write Chunk  */
  795.     size = pstr - chunkbuf;
  796.     if ((PushChunk(iff, 0, ID_YKCF, size)) ||
  797.         (WriteChunkBytes(iff, chunkbuf, size) != size) ||
  798.         (PopChunk(iff)))
  799.        return Writing_prefs_file_ERR;
  800.  
  801.     /* All OK. */
  802.     return NULL;
  803. }
  804.  
  805. static APTR
  806. WriteHotkey(struct IFFHandle *iff, UBYTE *chunkbuf, YakHotKey *yhk)
  807. {
  808.     UWORD          *puword=(UWORD *)chunkbuf;
  809.     UBYTE          *pstr;
  810.     void           *pvoid;
  811.     LONG           *plong;
  812.     UWORD           ol, optsnum;
  813.     OptDescription *curdesc;
  814.  
  815.     ULONG    size;
  816.  
  817.     *puword++  = yhk->yhk_Type;     /* Type  */
  818.     *puword++  = yhk->yhk_State;    /* State */
  819.     pstr = (UBYTE *)puword;
  820.  
  821.     strcpy(pstr, yhk->yhk_Name);   /* Name */
  822.     pstr += strlen(pstr)+1;
  823.  
  824.     /* Take care of non word aligned addresses for 68000 */
  825.     puword = (UWORD *)WORD_ALIGN(pstr);
  826.  
  827.     strcpy(pstr, yhk->yhk_KeyDef); /* KeyDef */
  828.     pstr += strlen(pstr)+1;
  829.  
  830.     /* Options */
  831.     /* Take care of non word aligned addresses for 68000 */
  832.     puword = (UWORD *)WORD_ALIGN(pstr);
  833.  
  834.     *puword++ = optsnum  = YHK_Takes_Opt(yhk);
  835.     pvoid = (void *)puword;
  836.  
  837.     for (ol=0; ol<optsnum; ol++)
  838.     {
  839.         UWORD as=0;   /* ArgStr number */
  840.         UWORD an=0;   /* ArgNum number */
  841.  
  842.         curdesc = yhktypes[yhk->yhk_Type].yhkt_OptsList[ol].Desc;
  843.  
  844.         puword = (UWORD *)pvoid;
  845.         *puword++ = yhk->yhk_Option[ol].Flags;
  846.         pvoid = (void *)puword;
  847.  
  848.         while (curdesc->Type != NO_OPT)
  849.         {
  850.             switch(curdesc->Type)
  851.             {
  852.                 case STRING_OPT:
  853.                     if (yhk->yhk_Option[ol].Flags & curdesc->LocalID)
  854.                     {
  855.                         pstr = (UBYTE *)pvoid;
  856.                         strcpy(pstr, yhk->yhk_Option[ol].ArgStr[as]);
  857.                         pstr += strlen(pstr)+1;
  858.  
  859.                         /* Take care of non word aligned addresses for 68000 */
  860.                         pvoid = (void *)WORD_ALIGN(pstr);
  861.                     }
  862.                     as++;
  863.                     break;
  864.  
  865.                 case INTEGER_OPT:
  866.                     if (yhk->yhk_Option[ol].Flags & curdesc->LocalID)
  867.                     {
  868.                         plong = (LONG *)pvoid;
  869.                         *plong++ =yhk->yhk_Option[ol].ArgNum[an];
  870.                         pvoid = (void *)plong;
  871.                     }
  872.                     an++;
  873.                     break;
  874.             }
  875.  
  876.             curdesc++;
  877.         }
  878.     }
  879.  
  880.  
  881.     /* Write Chunk */
  882.     size = (UBYTE *)pvoid - chunkbuf;
  883.     if ((PushChunk(iff, 0, ID_YKHK, size)) ||
  884.         (WriteChunkBytes(iff, chunkbuf, size) != size) ||
  885.         (PopChunk(iff)))
  886.        return Writing_prefs_file_ERR;
  887.  
  888.     /* All OK. */
  889.     return 0L;
  890. }
  891.  
  892. static APTR
  893. WriteHandlers(struct IFFHandle *iff, UBYTE *chunkbuf)
  894. {
  895.     UWORD  *puword=(UWORD *)chunkbuf;
  896.     UBYTE  *pstr;
  897.     register UWORD i;
  898.     ULONG    size;
  899.  
  900.     *puword++  = NUM_HANDLERS;
  901.     
  902.     for (i=0; i< NUM_HANDLERS; i++)
  903.     {
  904.         *puword++ = MouseCyclingHandlers[i].State;
  905.         *puword++ = MouseCyclingHandlers[i].RequiredClicks;
  906.         *puword++ = MouseCyclingHandlers[i].Options;
  907.         pstr = (UBYTE *)puword;
  908.         strcpy(pstr, MouseCyclingHandlers[i].KeyDef);
  909.         pstr += strlen(pstr)+1;
  910.         strcpy(pstr, MouseCyclingHandlers[i].ScreenPatternData.patstr);
  911.         pstr += strlen(pstr)+1;
  912.  
  913.         /* Take care of non word aligned addresses for 68000 */
  914.         puword = (UWORD *)WORD_ALIGN(pstr);
  915.     }
  916.  
  917.     /* Write Chunk */
  918.     size = (UBYTE *)puword - chunkbuf;
  919.     if ((PushChunk(iff, 0, ID_YKHD, size)) ||
  920.         (WriteChunkBytes(iff, chunkbuf, size) != size) ||
  921.         (PopChunk(iff)))
  922.        return Writing_prefs_file_ERR;
  923.  
  924.     /* All OK. */
  925.     return NULL;
  926. }
  927.  
  928. #endif
  929.